//****************************************************************************
//						BIST_MODE
//
//功能：自测试模式
//版本：v1.0		xhTang		2021/05/10
//说明：bist管脚，从外部pin输入，会有噪声干扰，需要做滤波毛刺处理。
//	V1.0测试ok，屏幕边缘无图像，闪动，初步判定为时钟不稳定。
//****************************************************************************
module BIST_MODE(
// 时钟输入
input	wire			sclk		,			//内部osc 30M

input	wire			reset_n		,
input	wire			BIST		,

//源输入
input	wire			ckin		,
input	wire	[1:0]	vsin		,
input	wire	[1:0]	hsin		,
input	wire	[1:0]	dein		,
input	wire	[47:0]	din			,

// 输出控制
output	wire			o_clk		,
output	wire	[1:0]	o_vs		,
output	wire	[1:0]	o_hs		,
output	wire	[1:0]	o_de		,
output	wire	[47:0]	o_data		);


reg  	[3:0]  	rst_init_cnt;
wire        	rst_init_n;
reg 	[31:0] 	rst_temp ;
reg 			SYS_RST_N;

parameter T4S  	= 32'd120_000;
parameter T3S	= 32'd90_000;

//产生PLL复位信号
always @(posedge  sclk )begin
	if(rst_init_cnt <4'h8) begin
		rst_init_cnt <= rst_init_cnt + 1;
	end
	else begin
		rst_init_cnt <= rst_init_cnt ;    
	end
end 

assign rst_init_n = rst_init_cnt[3];
 
always@(posedge sclk or negedge rst_init_n) begin
    if (rst_init_n == 1'b0) 
        rst_temp <= 'd0;
	else if(rst_temp < T4S)
		rst_temp <=rst_temp + 1'b1;
	else 
		rst_temp <=T4S;
end   

always @(posedge sclk or negedge rst_init_n) begin
    if (rst_init_n == 1'b0) 
        SYS_RST_N <=1'b0; 
	else if(rst_temp>32'd5&&rst_temp < T3S)
		SYS_RST_N <=1'b0;
	else 
		SYS_RST_N <=1'b1;
end


wire			CLK_100M,CLK_75M;
// 30M->74.25M
OCSPLL OCSPLL (
	.refclk		( sclk ),
	.reset		( ~SYS_RST_N ),
		
	.clk0_out	( CLK_100M ),
	.clk1_out	( CLK_75M ),
	.extlock	( extlock	)
);

assign	resetb = reset_n && extlock	;


reg			[2:0] 	BIST_reg	;
reg			[8:0] 	BIST_cnt	;
parameter	[31:0]	T_1ms = 31'd10_000;		//100M下的1ms
reg					BIST_SET	;
// 移位寄存器打拍
always @( posedge CLK_100M or negedge resetb ) 
	if ( resetb == 1'd0 ) 
		BIST_reg[2:0] <= 3'd0 ;	
	else
		BIST_reg[2:0] <= {BIST_reg[1:0],BIST};	

// BIST_cnt
// 复位上升沿，给初值0
// 计数满1ms停止计数
always @ ( posedge CLK_100M or negedge resetb )
	if ( resetb == 1'd0 )
		BIST_cnt <= 16'd0  ;
	else if ( BIST_reg[2:1] == 2'b01 ) 
		BIST_cnt <= 16'd0  ;
	else if ( BIST_cnt == T_1ms )
		BIST_cnt <= BIST_cnt ;
	else
		BIST_cnt <= BIST_cnt + 1'd1 ;

// 过滤低于1ms的毛刺		
always @ ( posedge CLK_100M or negedge resetb )		
	if ( resetb == 1'd0  ) 	
		BIST_SET <= 1'd0 ;
	else if (( BIST == 1'd1 ) && ( BIST_cnt == T_1ms ))
		BIST_SET <= 1'd1 ;
	else
		BIST_SET <= BIST_SET ;


// 计数给test_mode_in
reg			[31:0]	mode_cnt;
// 以下参数来源模块【f_timing_gen_03】
parameter	[7:0]	White	= 8'h03;
parameter	[7:0]	Black 	= 8'h07; 
parameter	[7:0]	Red		= 8'h04;
parameter	[7:0]	Green	= 8'h05;
parameter	[7:0]	Blue	= 8'h06;

parameter	[31:0]  T_2s	= 32'd200_000_000 - 32'd1;
parameter	[31:0]  T_4s	= 32'd400_000_000 - 32'd1;
parameter	[31:0]  T_6s	= 32'd600_000_000 - 32'd1;
parameter	[31:0]  T_8s	= 32'd800_000_000 - 32'd1;
parameter	[31:0]	T_10s	= 32'd1000_000_000 - 32'd1;		//100M下的10s

always @( posedge CLK_100M or negedge resetb )
	if ( resetb == 1'd0 )
		mode_cnt <= 32'd0	;
	else if ( mode_cnt == T_10s ) 
		mode_cnt <= 32'd0	;
	else
		mode_cnt <= mode_cnt + 32'd1 ;


reg		[7:0]	test_mode_in;
// 测试模式产生
// 白->黑->红->绿->蓝->白 循环 2秒切换
always @( posedge CLK_100M or negedge resetb )
	if ( resetb == 1'd0 )
		test_mode_in <= Red	;
	else
		case (mode_cnt)                 
			T_2s:		test_mode_in <= Green	;
			T_4s:		test_mode_in <= Blue	;
			T_6s:		test_mode_in <= Green	;
			T_8s:		test_mode_in <= White	;
			T_10s:		test_mode_in <= Black	;
			default:	test_mode_in <= test_mode_in	;
		endcase

//******************************************************************************
//                  LCD Panel Self-Test Patterns
//******************************************************************************
wire			oclk ,vsout,hsout,deout;
wire	[47:0]  dout;

assign	oclk = CLK_75M	;

 f_timing_gen_03 debug_timing(
        //时钟 & 复位
		.resetb			(resetb),
		.pclk			(oclk),
		
		
        //模式设置
        .half_flag		(1'b0),
		.test_mode_in	( test_mode_in ),
        //设置接口
		.base_addr		(24'h003050),
		
	    .set_clk		(1'b0),
	    .set_d_ok		(1'b0),
	    .set_addr		(24'h0),
	    .set_data		(8'h0),

        //设置输出
        .p_width    	(),
        .lan_num    	(),
		.VH_POLORITY	(),
	
		.vsin			(1'b0),
		
        //pclk控制时序
		.vs_a			(),
		.de_a			(),
		.de_pre			(),
		
        //调试用图像数据
		.dout_t			(),
		
        //最终输出时序
		.oclk			(oclk),
		.vsout			(vsout),
		.hsout			(hsout),
		.deout			(deout),
		.dout			(dout),
		
		//TCON辅助时序        
/*		.TP				( TP1 ),
        .POL			( POL ),
        .STV			( STV_IC ),
        .CPV1			( CLK1_IC ),
        .CPV2			( CLK2_IC ),
        .CLR			( CLR_IC ),
*/
		//调试信号
		.tout			()
		); 

		
EG_LOGIC_BUFGMUX #(
	.INIT_OUT		( "0" ),
	.PRESELECT_I0	( "TRUE" ),
	.PRESELECT_I1	( "FALSE" )
)
BUFGMUX(
	.i0	( oclk ),	//BIST 为1 输出此时钟
	.i1	( ckin ),	//BIST 为0 输出此时钟
	.s	( BIST ),
	.o	( o_clk )); // global clk switch mux


// assign	o_clk	= BIST ? oclk  : ckin	;
assign	o_vs	= BIST ? {vsout,vsout} : vsin	;
assign	o_hs	= BIST ? {hsout,hsout} : hsin	;
assign	o_de	= BIST ? {deout,deout} : dein	;
assign	o_data  = BIST ? dout  : din	; 


endmodule